package model

import (
	"easyVolunteer/utils"
	"easyVolunteer/utils/upload"
	"fmt"
	"github.com/xuri/excelize/v2"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
	"log"
	"strconv"
	"time"
)

var globalDb *gorm.DB

func InitDb() {
	dns := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		utils.DbUser,
		utils.DbPassWord,
		utils.DbHost,
		utils.DbPort,
		utils.DbName)

	db, err := gorm.Open(mysql.Open(dns), &gorm.Config{
		DisableForeignKeyConstraintWhenMigrating: true,
		NamingStrategy: schema.NamingStrategy{
			SingularTable: false,
			TablePrefix:   "t_",
		},
		SkipDefaultTransaction: true,
	})

	if err != nil {
		log.Println("数据库连接失败,err:", err)
	}
	globalDb = db
	err = db.AutoMigrate(&User{}, &Activity{}, &UserInfo{}, &UserLogin{}) //TODO 数据库自动迁移
	if err != nil {
		log.Println("数据库自动迁移失败，err:", err)
	}
	sqlDb, _ := db.DB()

	sqlDb.SetMaxIdleConns(10)                  // 连接池中的最大闲置连接数
	sqlDb.SetMaxOpenConns(100)                 // 数据库的最大连接数量
	sqlDb.SetConnMaxLifetime(10 * time.Second) // 连接的最大可复用时间

}

func ReadDataFromExcel() {
	f, err := excelize.OpenFile("Q:\\Project\\easyVolunteer\\model\\全校学生数据库ROOT.xlsx")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()
	// 获取工作表中指定单元格的值

	//获取 Sheet1 上所有单元格
	rows, err := f.GetRows("Sheet0")
	if err != nil {
		fmt.Println(err)
		return
	}
	for _, row := range rows {
		var u UserInfo
		u.Name = row[0]
		u.UserID = row[2]
		u.GeneralInfoCode = row[3] + row[4] + row[8] + row[9]

		if row[1] == "男" {
			u.GeneralInfoCode += "1"
		} else if row[1] == "女" {
			u.GeneralInfoCode += "2"
		} else {
			fmt.Println(row[1])
		}

		fmt.Println(u.UserID, u.Name, u.GeneralInfoCode)
		globalDb.Create(&UserInfo{UserID: u.UserID, Name: u.Name, GeneralInfoCode: u.GeneralInfoCode})
	}
}

func PassWordTest() {
	f, err := excelize.OpenFile("Q:\\Project\\easyVolunteer\\model\\test.xlsx")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()

	rows, err := f.GetRows("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, row := range rows {
		var u UserLogin
		//id, _ := strconv.Atoi(row[0])
		u.UserID = row[0]
		const cost = 5

		s := []byte(row[1])
		s = s[12:]
		fmt.Println(string(s))
		HashPw, err := bcrypt.GenerateFromPassword(s, cost)
		fmt.Println("密码", string(HashPw))
		if err != nil {
			log.Fatal(err)
		}

		u.PassWord = string(HashPw)
		fmt.Println(u.UserID)
		globalDb.Create(&u)
	}

}

func GuanLian() {
	u := User{UserID: "3200421039"}
	var a []Activity
	globalDb.Model(&u).Association("Activities").Find(&a)
	for _, i := range a {
		fmt.Println(i.ActivityID)
	}

}

func CurrencyTest() {
	f, err := excelize.OpenFile("Q:\\Project\\easyVolunteer\\model\\test.xlsx")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func() {
		if err := f.Close(); err != nil {
			fmt.Println(err)
		}
	}()

	rows, err := f.GetRows("Sheet1")
	if err != nil {
		fmt.Println(err)
		return
	}

	for i, row := range rows {
		if i == 100 {
			break
		}
		fmt.Println(i)
		userID := row[0]
		JoinActivity(278392133738565, userID)
	}
}

func Digits(num uint64) uint8 {
	var i uint8 = 0
	for num != 0 {
		i++
		num /= 10
	}
	return i
}

func WriteExcel() {
	f := excelize.NewFile()
	index := f.NewSheet("测试")

	u, err := CalculateSummaryData("15442061", "1990-01-01", "2025-11-20", 10, 20)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(u)

	rowIndex := 1
	for _, v := range u {
		// 即使活动总数为零也要写入记录
		if len(v.Activities) == 0 {
			writeUserInfo(rowIndex, v, f)
			rowIndex++
			continue
		}

		for _, a := range v.Activities {
			writeUserInfo(rowIndex, v, f)
			writeActivityINfo(rowIndex, a, f)
			rowIndex++
		}
	}
	f.SetActiveSheet(index)
	if err := f.SaveAs("结果.xlsx"); err != nil {
		fmt.Println(err)
	}
}

func writeUserInfo(row int, u User, f *excelize.File) {
	f.SetCellValue("测试", "A"+strconv.Itoa(row), u.UserID)
	f.SetCellValue("测试", "B"+strconv.Itoa(row), u.TotalHours)
	f.SetCellValue("测试", "C"+strconv.Itoa(row), "未参加活动")
}
func writeActivityINfo(row int, a Activity, f *excelize.File) {
	f.SetCellValue("测试", "C"+strconv.Itoa(row), a.ActivityID)
	f.SetCellValue("测试", "D"+strconv.Itoa(row), a.Start)
	f.SetCellValue("测试", "E"+strconv.Itoa(row), a.End)
	f.SetCellValue("测试", "F"+strconv.Itoa(row), a.OwnerID)
	f.SetCellValue("测试", "G"+strconv.Itoa(row), a.Duration)
	f.SetCellValue("测试", "H"+strconv.Itoa(row), a.Name)
	f.SetCellValue("测试", "I"+strconv.Itoa(row), a.Comments)
}

func TestUpload() {
	upload.UpLoadToOss("./结果.xlsx")
}
